home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
dpmigcc5.zip
/
RSX
/
SOURCE
/
START32.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-12
|
13KB
|
396 lines
/*****************************************************************************
* FILE: start32 *
* *
* DESC: *
* - DPMI-switches for DPMI 0.9 *
* - init some protected mode interrupts *
* - init exception handlers *
* - clean up for exit *
* *
* Copyright (C) 1993,1994 *
* Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld *
* email: rainer@mathematik.uni-bielefeld.de *
* *
*****************************************************************************/
#include "DPMI.H"
#include "DPMI10.H"
#include "PRINTF.H"
#include "PROCESS.H"
#include "RSX.H"
#include "ADOSX32.H"
#include "CDOSX32.H"
#include "EXCEP32.H"
#include "START32.H"
#include "COPY32.H"
#include "SYSDEP.H"
/* global extender segments,selectors */
UINT cs16real, ds16real; /* 16-bit segments for extender */
UINT code16sel, data16sel; /* 16-bit cs,ds for extender */
UINT stack16sel; /* 16-bit stack sel */
DWORD stackp16; /* 16-bit stack offset (use long!) */
UINT sel_incr; /* increment to next selector */
UINT dosmem_sel; /* selector for the first MB */
UINT fpu_status;
WORD DPMIversion = 0;
WORD previous_client_cs;
char dpmi10; /* DPMI 1.0 server */
char dpmi10_map; /* DPMI 1.0 mapping supported */
char dpmi10_page; /* DPMI 1.0 access/dirty supported */
char dpmi10_zero; /* DPMI 1.0 demand zero supported */
/* private vars */
static WORD DPMIdata_para_needed;
static WORD DPMIdata_segm_address;
static char fpu_status_init;
/*
** back to real-mode, terminate ( int0x21 must set to orginal )
*/
#ifndef __EMX__
extern void ProtectedModeSwitch(void);
extern void RealModeSwitch(void);
extern void _cexit(void);
#endif
void protected_to_real(WORD errorlevel)
{
if (fpu_status_init)
DpmiSetCoproStatus(fpu_status & 3);
#ifdef _MSC_VER
RealModeSwitch(); /* clean up in real mode */
_cexit();
ProtectedModeSwitch();
#endif
#ifdef _TURBOC_
RealModeSwitch(); /* clean up interrupt vector */
_restorezero();
ProtectedModeSwitch();
#endif
dos_exit(errorlevel);
/* program ends here */
}
void init_real_mode(void)
{
#ifdef __EMX__
DWORD base_addr; /* rsx32 is in protected mode */
code16sel = GetCS();
data16sel = stack16sel = GetDS();
GetBaseAddress(code16sel, &base_addr);
cs16real = (UINT) (base_addr >> 4);
GetBaseAddress(data16sel, &base_addr);
ds16real = (UINT) (base_addr >> 4);
#else /* rsx16 is in real mode */
cs16real = GetCS();
ds16real = GetDS();
#endif
}
/*
** switch to protected-mode via DPMI-host
*/
int real_to_protected(WORD mode)
{
#ifndef __EMX__
WORD DPMIflags;
BYTE processor;
DWORD PM_jump; /* switch to protmode jump */
clearregs();
/* setbuf(stdout,NULL); */
if (GetDpmiEntryPoint(&PM_jump, &DPMIdata_para_needed,
&DPMIflags, &DPMIversion, &processor)) {
puts("No DPMI-host found!");
return -1;
}
if (mode == 1 && !(DPMIflags & 1)) {
puts("32bit programs not supported\n");
return -1;
}
if (DPMIdata_para_needed) { /* get DPMI ring 0 stack */
DPMIdata_segm_address = GetDpmiHostParagraph(DPMIdata_para_needed);
if (!DPMIdata_segm_address) {
puts("Can't alloc memory for the DPMI-host-stack");
return -1;
}
}
if (DpmiEnterProtectedMode(PM_jump, mode, DPMIdata_segm_address)) {
puts("can't switch to Protected Mode");
return -1;
}
/* Now we are in Protected Mode */
/* lock DPMI-stack */
if (DPMIdata_para_needed) {
LockLinRegion((DWORD) DPMIdata_segm_address << 4,
(DWORD) DPMIdata_para_needed << 4);
}
/* get prot-mode extender segments */
code16sel = GetCS();
data16sel = stack16sel = GetDS();
#endif
return 0;
}
/*
** test DPMI server
*/
int test_dpmi_capabilities(void)
{
if (!DPMIversion) {
DPMIVERSION ver;
GetDPMIVersion(&ver);
DPMIversion = ((WORD)ver.major << 8) | ver.minor;
if (opt_printall)
printf("DPMI version %d.%d\n", ver.major, ver.minor);
}
if (!opt_force_dpmi09) {
DPMICAP cap;
if ((DPMIversion >> 8) >= 1)
dpmi10 = 1;
if (!GetDPMICapabilities(&cap, iobuf)) {
if (cap.bits & 1)
dpmi10_page = 1;
if (cap.bits & 8)
dpmi10_map = 1;
if (cap.bits & 16)
dpmi10_zero = 1;
if (dpmi10_page & dpmi10_map) /* give 0.9x a chance */
dpmi10 = 1;
}
}
sel_incr = SelInc();
/* build selector for first megabyte */
AllocLDT(1, &dosmem_sel);
SetBaseAddress(dosmem_sel, 0L);
SetAccess(dosmem_sel, APP_DATA_SEL, BIG_BIT | GRANULAR_BIT);
SetLimit(dosmem_sel, 1024L * 1024L - 1L);
return 0;
}
static POINTER16_32 int21v; /* old int21h handler address */
static POINTER16_32 int10v; /* old int10h handler address */
static POINTER16_32 int33v; /* old int33h handler address */
static POINTER16_32 ctrlcv; /* old control-c handler */
static POINTER16_32 timerv; /* old timer handler */
static POINTER16_32 debintv; /* old int3 handler */
static POINTER16_32 excep0v, excep1v, excep2v, excep3v, excep4v, excep5v,
excep6v, excep7v, excep8v, excep9v, excep10v, excep11v, excep12v, excep13v, excep14v,
excep15v, excep16v, excep17v;
int hangin21;
int hangin_extender(void)
{
UINT alias_cs;
int stackp;
/* entry stack for interrupts, exceptions */
stackp16 = (UINT) & stackp;
/* store ds-sel in code for some interrupt handler */
if (CreatAlias(code16sel, &alias_cs))
return -1;
/* store 16bit data selector in load_ds function */
store32(alias_cs, (DWORD) (UINT) extender_ds, (DWORD) data16sel);
/* hang in int 0x21 */
if (GetProtModeVector32(0x21, &int21v.sel, &int21v.off) == -1) {
puts("error:can't get int21");
return -1;
}
if (SetProtModeVector32(0x21, code16sel, (DWORD) (UINT) doscall) == -1) {
puts("error:can't set int21");
return -1;
}
hangin21 = 1;
previous_client_cs = int21v.sel;
align_iobuf();
/* chain to default int 0x21 */
store32(alias_cs, (DWORD) (unsigned) &int21vsel, (DWORD) int21v.sel);
store32(alias_cs, (DWORD) (unsigned) &int21voff, (DWORD) int21v.off);
/* set new bios int10 for vesa calls */
if (GetProtModeVector32(0x10, &int10v.sel, &int10v.off)<0)
puts("int10 fail:get");
if (SetProtModeVector32(0x10, code16sel, (DWORD) (UINT) bioscall)<0)
puts("int10 fail:set");
store32(alias_cs, (DWORD) (unsigned) &int10vsel, (DWORD) int10v.sel);
store32(alias_cs, (DWORD) (unsigned) &int10voff, (DWORD) int10v.off);
FreeLDT(alias_cs);
/* MOUSE */
GetProtModeVector32(0x33, &int33v.sel, &int33v.off);
SetProtModeVector32(0x33, code16sel, (DWORD) (UINT) mousecall);
/* get all exception vectors */
GetExceptionVector32(0, &excep0v.sel, &excep0v.off);
GetExceptionVector32(1, &excep1v.sel, &excep1v.off);
GetExceptionVector32(2, &excep2v.sel, &excep2v.off);
GetExceptionVector32(3, &excep3v.sel, &excep3v.off);
GetExceptionVector32(4, &excep4v.sel, &excep4v.off);
GetExceptionVector32(5, &excep5v.sel, &excep5v.off);
GetExceptionVector32(6, &excep6v.sel, &excep6v.off);
GetExceptionVector32(7, &excep7v.sel, &excep7v.off);
GetExceptionVector32(8, &excep8v.sel, &excep8v.off);
GetExceptionVector32(9, &excep9v.sel, &excep9v.off);
GetExceptionVector32(10, &excep10v.sel, &excep10v.off);
GetExceptionVector32(11, &excep11v.sel, &excep11v.off);
GetExceptionVector32(12, &excep12v.sel, &excep12v.off);
GetExceptionVector32(13, &excep13v.sel, &excep13v.off);
GetExceptionVector32(14, &excep14v.sel, &excep14v.off);
GetExceptionVector32(15, &excep15v.sel, &excep15v.off);
GetExceptionVector32(16, &excep16v.sel, &excep16v.off);
GetExceptionVector32(17, &excep17v.sel, &excep17v.off);
/* set all exception vectors */
if (!opt_debugrsx) {
SetExceptionVector32(1, code16sel, (DWORD) (UINT) (excep1_386));
SetExceptionVector32(3, code16sel, (DWORD) (UINT) (excep3_386));
}
SetExceptionVector32(0, code16sel, (DWORD) (UINT) (excep0_386));
SetExceptionVector32(2, code16sel, (DWORD) (UINT) (excep2_386));
SetExceptionVector32(4, code16sel, (DWORD) (UINT) (excep4_386));
SetExceptionVector32(5, code16sel, (DWORD) (UINT) (excep5_386));
SetExceptionVector32(6, code16sel, (DWORD) (UINT) (excep6_386));
SetExceptionVector32(7, code16sel, (DWORD) (UINT) (excep7_386));
SetExceptionVector32(8, code16sel, (DWORD) (UINT) (excep8_386));
SetExceptionVector32(9, code16sel, (DWORD) (UINT) (excep9_386));
SetExceptionVector32(10, code16sel, (DWORD) (UINT) (excep10_386));
SetExceptionVector32(11, code16sel, (DWORD) (UINT) (excep11_386));
SetExceptionVector32(12, code16sel, (DWORD) (UINT) (excep12_386));
SetExceptionVector32(13, code16sel, (DWORD) (UINT) (excep13_386));
SetExceptionVector32(15, code16sel, (DWORD) (UINT) (excep15_386));
SetExceptionVector32(16, code16sel, (DWORD) (UINT) (excep16_386));
SetExceptionVector32(17, code16sel, (DWORD) (UINT) (excep17_386));
if (dpmi10)
SetExceptionVector32(14, code16sel, (DWORD) (UINT) (page_fault));
else
SetExceptionVector32(14, code16sel, (DWORD) (UINT) (excep14_386));
/* TIMER */
GetProtModeVector32(0x1C, &timerv.sel, &timerv.off);
SetProtModeVector32(0x1C, code16sel, (DWORD) (UINT) timer_handler);
/* CTRL-C */
GetProtModeVector32(0x23, &ctrlcv.sel, &ctrlcv.off);
SetProtModeVector32(0x23, code16sel, (DWORD) (UINT) prot_cbrk);
/* debug int3 */
if (!opt_debugrsx) {
GetProtModeVector32(0x03, &debintv.sel, &debintv.off);
SetProtModeVector32(0x03, code16sel, (DWORD) (UINT) debug_entry);
}
return 0;
}
/*
** init fpu
*/
int init_fpu(void)
{
/* Get FPU status, if user allow this (not -e0) */
if (opt_force_copro != 1) {
if (DpmiGetCoproStatus(&fpu_status))
fpu_status = 0;
if (opt_printall)
printf("fpu_status = 0x%X\n", fpu_status);
}
/*
** copro = 0 , with -e option : if no 387, set copro = 2
** copro = 1 , default : enable FPU
** copro = 3 , if no FPU : enable kernel FPU emulation
*/
if (copro == 0 && !npx_present) /* catch missing 387 */
if (! opt_force_copro)
copro = 2;
if (copro) {
fpu_status_init = 1;
if (DpmiSetCoproStatus(copro))
puts("Warning: No DPMI-server FPU support");
}
return 0;
}
static void free_emu_mem(void)
{
UnlockLinRegion(RSX_PROCESS.memaddress, RSX_PROCESS.membytes);
if (rsx387_in_dosmem)
FreeDosMem((WORD) RSX_PROCESS.memhandle);
else
FreeMem(RSX_PROCESS.memhandle);
FreeLDT(RSX_PROCESS.code32sel);
FreeLDT(RSX_PROCESS.data32sel);
FreeLDT(RSX_PROCESS.data32sel + sel_incr);
}
/* clean up interrupt handlers, exceptions, memory ... */
void clean_up(void)
{
flush_all_buffers();
clearregs();
if (opt_printall)
puts("cleanup now");
if (DPMIdata_para_needed)
UnlockLinRegion((DWORD) DPMIdata_segm_address << 4,
(DWORD) DPMIdata_para_needed << 4);
/* unset 387-usage (otherwise: crash) */
if (fpu_status_init) {
DpmiSetCoproStatus(fpu_status & 3);
if (copro == 3 && emu_sel != 0)
free_emu_mem();
}
fpu_status_init = 0;
copro = 0;
SetProtModeVector32(0x21, int21v.sel, int21v.off);
SetProtModeVector32(0x10, int10v.sel, int10v.off);
SetProtModeVector32(0x1C, timerv.sel, timerv.off);
SetProtModeVector32(0x23, ctrlcv.sel, ctrlcv.off);
SetProtModeVector32(0x03, debintv.sel, debintv.off);
if (!opt_debugrsx) {
SetExceptionVector32(1, excep1v.sel, excep1v.off);
SetExceptionVector32(3, excep3v.sel, excep3v.off);
}
SetExceptionVector32(0, excep0v.sel, excep0v.off);
SetExceptionVector32(2, excep2v.sel, excep2v.off);
SetExceptionVector32(4, excep4v.sel, excep4v.off);
SetExceptionVector32(5, excep5v.sel, excep5v.off);
SetExceptionVector32(6, excep6v.sel, excep6v.off);
SetExceptionVector32(7, excep7v.sel, excep7v.off);
SetExceptionVector32(8, excep8v.sel, excep8v.off);
SetExceptionVector32(9, excep9v.sel, excep9v.off);
SetExceptionVector32(10, excep10v.sel, excep10v.off);
SetExceptionVector32(11, excep11v.sel, excep11v.off);
SetExceptionVector32(12, excep12v.sel, excep12v.off);
SetExceptionVector32(13, excep13v.sel, excep13v.off);
SetExceptionVector32(14, excep14v.sel, excep14v.off);
SetExceptionVector32(15, excep15v.sel, excep15v.off);
SetExceptionVector32(16, excep16v.sel, excep16v.off);
SetExceptionVector32(17, excep17v.sel, excep17v.off);
}